#include "udp_service.hpp"
#include "event_loop.hpp"
#include "event_trace.hpp"
#include <error.h>

using namespace event_framework;

bool UdpService::Init()
{
    int ret = socket.Create(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_UDP);
    if (ret < 0)
    {
        EVENT_TRACE_ERROR("[UdpService::Init] create socket failed with err=" << error);
        return false;
    }
    ret = socket.Bind();
    if (ret < 0)
    {
        EVENT_TRACE_ERROR("[UdpService::Init] bind socket failed with err=" << error);
        return false;
    }
    loop.Accept(std::bind(&UdpService::InitChannel, this));
    return true;
}

void UdpService::InitChannel()
{
    channel = std::make_shared<Channel>(loop, socket.GetFd());
    ASSERT(channel != nullptr);
    if (eventCallback.readableCallback)
    {
        channel->ConcernReadableEvent([this]()->void
        {
            eventCallback.readableCallback(socket);
        });
    }
    if (eventCallback.writeableCallback)
    {
        channel->ConcernWriteableEvent([this]()->void
        {
            eventCallback.writeableCallback(socket);
        });
    }
    if (eventCallback.exceptionCallback)
    {
        channel->ConcernExceptionEvent([this](int err)->void
        {
            eventCallback.exceptionCallback(socket, err);
        });
    }
    if (eventCallback.closedCallback)
    {
        channel->ConcernClosedEvent([this]()->void
        {
            eventCallback.closedCallback(socket);
        });
    }
}
